#include <wx/dcmemory.h>
#include "wxsitemeditor.h"
#include "wxsitemeditorcontent.h"
#include "wxsitemfactory.h"
#include "wxsitemresdata.h"
#include "wxstoolspace.h"
#include "wxsitem.h"
#include "wxstool.h"
#include "wxsparent.h"
#include "../wxsproject.h"
#include <logmanager.h>

namespace {
  const long wxsInsPointId   = wxNewId();
  const long wxsInsIntoId    = wxNewId();
  const long wxsInsBeforeId  = wxNewId();
  const long wxsInsAfterId   = wxNewId();
  const long wxsDelId        = wxNewId();
  const long wxsPreviewId    = wxNewId();
  const long wxsQuickPropsId = wxNewId();

  inline int ToolIconSize() { return Manager::Get()->GetConfigManager( _T( "wxsmith" ) )->ReadInt( _T( "/tooliconsize" ), 32L ); }
  inline int PalIconSize()  { return Manager::Get()->GetConfigManager( _T( "wxsmith" ) )->ReadInt( _T( "/paletteiconsize" ), 16L ); }
}

wxsItemEditor::wxsItemEditor( wxWindow* parent, wxsItemRes* Resource ):
  wxsEditor( parent, wxEmptyString, Resource ),
  m_Data( 0 ),
  m_Content( 0 ),
  m_WidgetsSet( 0 ),
  m_VertSizer( 0 ),
  m_HorizSizer( 0 ),
  m_QPSizer( 0 ),
  m_OpsSizer( 0 ),
  m_QPArea( 0 ),
  m_InsIntoBtn( 0 ),
  m_InsBeforeBtn( 0 ),
  m_InsAfterBtn( 0 ),
  m_DelBtn( 0 ),
  m_PreviewBtn( 0 ),
  m_QuickPanelBtn( 0 ),
  m_TopPreview( 0 ),
  m_PreviewBackground( 0 ),
  m_InsType( itPoint ),
  m_InsTypeMask( itPoint ),
  m_QuickPropsOpen( false ),
  m_PopupCaller( 0 ) {
  InitializeResourceData();
  InitializeVisualStuff();
  m_AllEditors.insert( this );
}

wxsItemEditor::~wxsItemEditor() {
  delete m_Data;
  m_AllEditors.erase( this );
}

void wxsItemEditor::InitializeResourceData() {
  m_Data = GetItemRes()->BuildResData( this );
  if( !m_Data->IsOk() ) {
  }
  if( GetItemRes()->GetEditMode() == wxsItemRes::File ) {
    InitFilename( GetXrcFileName() );
    SetTitle( m_Shortname );
  } else {
    InitFilename( GetWxsFileName() );
    SetTitle( m_Shortname );
  }
}

void wxsItemEditor::InitializeVisualStuff() {
  InitializeImages();
  m_VertSizer = new wxBoxSizer( wxVERTICAL );
  m_WidgetsSet = new wxNotebook( this, -1 );
  BuildPalette( m_WidgetsSet );
  m_ToolSpace = new wxsToolSpace( this, m_Data );
  m_VertSizer->Add( m_ToolSpace, 0, wxEXPAND );
  m_HorizSizer = new wxBoxSizer( wxHORIZONTAL );
  m_VertSizer->Add( m_HorizSizer, 1, wxEXPAND );
  m_VertSizer->Add( m_WidgetsSet, 0, wxEXPAND );
  m_Content = new wxsItemEditorContent( this, m_Data, this );
  m_HorizSizer->Add( m_Content, 1, wxEXPAND );
  m_QPArea = new wxScrolledWindow( this, -1, wxDefaultPosition, wxDefaultSize, wxVSCROLL | wxHSCROLL | wxSUNKEN_BORDER );
  m_QPArea->SetScrollbars( 0, 5, 0, 0 );
  m_HorizSizer->Add( m_QPArea, 0, wxEXPAND );
  m_QPSizer = new wxBoxSizer( wxVERTICAL );
  m_QPArea->SetSizer( m_QPSizer );
  m_OpsSizer = new wxBoxSizer( wxVERTICAL );
  m_HorizSizer->Add( m_OpsSizer, 0, wxEXPAND );
  m_OpsSizer->Add( m_InsPointBtn  = new wxBitmapButton( this, wxsInsPointId, m_InsPointImg ) );
  m_OpsSizer->Add( m_InsIntoBtn   = new wxBitmapButton( this, wxsInsIntoId, m_InsIntoImg ) );
  m_OpsSizer->Add( m_InsBeforeBtn = new wxBitmapButton( this, wxsInsBeforeId, m_InsBeforeImg ) );
  m_OpsSizer->Add( m_InsAfterBtn  = new wxBitmapButton( this, wxsInsAfterId, m_InsAfterImg ) );
  m_OpsSizer->Add( 1, 5 );
  m_OpsSizer->Add( m_DelBtn = new wxBitmapButton( this, wxsDelId, m_DelImg ) );
  m_OpsSizer->Add( m_PreviewBtn = new wxBitmapButton( this, wxsPreviewId, m_PreviewImg ) );
  m_OpsSizer->Add( 1, 5 );
  m_OpsSizer->Add( m_QuickPanelBtn = new wxBitmapButton( this, wxsQuickPropsId, m_QuickPropsImgOpen ) );
  m_InsPointBtn ->SetToolTip( _T( "用鼠标插入新的小部件" ) );
  m_InsIntoBtn ->SetToolTip( _T( "在当前选择中插入新的小部件" ) );
  m_InsBeforeBtn ->SetToolTip( _T( "在当前选择之前插入新的小部件" ) );
  m_InsAfterBtn ->SetToolTip( _T( "在当前选择后插入新的小部件" ) );
  m_DelBtn ->SetToolTip( _T( "删除当前选择" ) );
  m_PreviewBtn ->SetToolTip( _T( "显示预览" ) );
  m_QuickPanelBtn->SetToolTip( _T( "打开/关闭 属性面板" ) );
  SetSizer( m_VertSizer );
  SetInsertionTypeMask( 0 );
  ToggleQuickPropsPanel( false );
  RebuildPreview();
  UpdateSelection();
}

void wxsItemEditor::ConfigChanged() {
  ReloadImages();
  RefreshContents();
}

void wxsItemEditor::ReloadImages() {
  m_ImagesLoaded = false;
  InitializeImages();
  for( WindowSet::iterator i = m_AllEditors.begin(); i != m_AllEditors.end(); ++i ) {
    ( *i )->RebuildIcons();
  }
}

void wxsItemEditor::RefreshContents() {
  for( WindowSet::iterator i = m_AllEditors.begin(); i != m_AllEditors.end(); ++i ) {
    ( *i )->RebuildPreview();
  }
}

void wxsItemEditor::RebuildPreview() {
  if( !m_Content ) {
    return;
  }
  m_Content->BeforePreviewChanged();
  m_ToolSpace->BeforePreviewChanged();
  Freeze();
  if( m_PreviewBackground ) {
    m_Content->SetSizer( 0 );
    m_PreviewBackground->Destroy();
    m_PreviewBackground = 0;
    m_TopPreview = 0;
  }
  m_PreviewBackground = new wxPanel( m_Content, -1, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER );
  wxObject* TopPreviewObject = m_Data->GetRootItem()->BuildPreview( m_PreviewBackground, 0 );
  m_TopPreview = wxDynamicCast( TopPreviewObject, wxWindow );
  if( !m_TopPreview ) {
    Manager::Get()->GetLogManager()->DebugLog( _T( "One of root items returned class not derived from wxWindow" ) );
    m_PreviewBackground->Destroy();
    m_PreviewBackground = 0;
    m_TopPreview = 0;
  } else {
    wxSizer* BackgroundSizer = new wxBoxSizer( wxHORIZONTAL );
    BackgroundSizer->Add( m_TopPreview, 0, 0, 0 );
    m_PreviewBackground->SetSizer( BackgroundSizer );
    BackgroundSizer->Fit( m_PreviewBackground );
    wxSizer* NewSizer = new wxGridSizer( 1 );
    NewSizer->Add( m_PreviewBackground, 0, wxALL, 10 );
    m_Content->SetVirtualSizeHints( 1, 1 );
    m_Content->SetSizer( NewSizer );
    NewSizer->SetVirtualSizeHints( m_Content );
    m_PreviewBackground->Layout();
    m_Content->Layout();
    m_HorizSizer->Layout();
  }
  m_ToolSpace->AfterPreviewChanged();
  if( m_ToolSpace->AreAnyTools() ) {
    m_VertSizer->Show( m_ToolSpace, true, false );
  } else {
    m_VertSizer->Show( m_ToolSpace, false, false );
  }
  m_VertSizer->Layout();
  Layout();
  Thaw();
  Refresh();
  m_Content->AfterPreviewChanged();
}

void wxsItemEditor::UpdateSelection() {
  if( !m_Content ) {
    return;
  }
  m_Content->RefreshSelection();
  m_ToolSpace->RefreshSelection();
  wxsItem* Item = m_Data->GetRootSelection();
  int itMask = 0;
  if( Item ) {
    if( Item->GetParent() ) {
      if( Item->GetType() != wxsTSizer ||
          Item->GetParent()->GetType() == wxsTSizer ) {
        itMask |= itBefore | itAfter;
      }
    }
    if( Item->ConvertToParent() ) {
      itMask |= itInto;
    }
  }
  if( m_Data->GetRootItem()->ConvertToParent() ) {
    itMask |= itPoint;
  }
  SetInsertionTypeMask( itMask );
  RebuildQuickProps( Item );
}

bool wxsItemEditor::Save() {
  if( !m_Data->Save() ) {
  }
  UpdateModified();
  return true;
}

bool wxsItemEditor::GetModified() const {
  return m_Data ? m_Data->GetModified() : false;
}

void wxsItemEditor::UpdateModified() {
  if( m_Data && m_Data->GetModified() ) {
    SetTitle( _T( "*" ) + GetShortName() );
  } else {
    SetTitle( GetShortName() );
  }
}

bool wxsItemEditor::CanUndo() const {
  return m_Data ? m_Data->CanUndo() : false;
}

bool wxsItemEditor::CanRedo() const {
  return m_Data ? m_Data->CanRedo() : false;
}

void wxsItemEditor::Undo() {
  if( m_Data ) {
    m_Data->Undo();
  }
}

void wxsItemEditor::Redo() {
  if( m_Data ) {
    m_Data->Redo();
  }
}

bool wxsItemEditor::HasSelection() const {
  return m_Data ? m_Data->AnySelected() : false;
}

bool wxsItemEditor::CanPaste() const {
  return m_Data ? m_Data->CanPaste() : false;
}

bool wxsItemEditor::IsReadOnly() const {
  return m_Data ? m_Data->IsReadOnly() : false;
}

void wxsItemEditor::Cut() {
  if( m_Data ) {
    m_Data->Cut();
  }
}

void wxsItemEditor::Copy() {
  if( m_Data ) {
    m_Data->Copy();
  }
}

void wxsItemEditor::Paste() {
  if( !m_Data ) {
    return;
  }
  wxsItem* Reference = GetReferenceItem( m_InsType );
  if( !Reference ) {
    return;
  }
  wxsParent* Parent = Reference->GetParent();
  int RefIndex = Parent ? Parent->GetChildIndex( Reference ) : -1;
  switch( m_InsType ) {
  case itAfter:
    RefIndex++;
    break;
  case itInto:
    Parent = Reference->ConvertToParent();
    RefIndex = Parent ? Parent->GetChildCount() : 0;
    break;
  default:
    break;
  }
  m_Data->Paste( Parent, RefIndex );
}

void wxsItemEditor::InsertRequest( const wxString& Name ) {
  const wxsItemInfo* Info = wxsItemFactory::GetInfo( Name );
  if( !Info ) {
    return;
  }
  bool IsTool = Info->Type == wxsTTool;
  if( !IsTool && m_InsType == itPoint ) {
    StartInsertPointSequence( Info );
    return;
  }
  wxsItem* Reference = GetReferenceItem( m_InsType );
  if( !Reference ) {
    Manager::Get()->GetLogManager()->DebugLog( _T( "wxSmith: No item selected - couldn't create new item" ) );
    return;
  }
  wxsItem* New = wxsItemFactory::Build( Name, m_Data );
  if( !New ) {
    Manager::Get()->GetLogManager()->DebugLog( _T( "wxSmith: Couldn't generate item inside factory" ) );
    return;
  }
  m_Data->BeginChange();
  wxsParent* Parent = Reference->GetParent();
  int RefIndex = Parent ? Parent->GetChildIndex( Reference ) : -1;
  switch( m_InsType ) {
  case itAfter:
    RefIndex++;
  case itBefore:
    if( Parent ) {
      if( IsTool &&
          ( !Parent->ConvertToTool() ||
            !New->CanAddToParent( Parent, false ) ) ) {
        if( !New->ConvertToTool()->CanAddToResource( m_Data, true ) ) {
          delete New;
        } else {
          if( m_Data->InsertNewTool( New->ConvertToTool() ) )
          { m_Data->SelectItem( New, true ); }
        }
      } else {
        if( m_Data->InsertNew( New, Parent, RefIndex ) ) {
          m_Data->SelectItem( New, true );
        }
      }
    } else
    { delete New; }
    break;
  case itInto:
  case itPoint: {
    if( IsTool &&
        ( !Reference->ConvertToTool() ||
          !New->CanAddToParent( Reference->ConvertToParent(), false ) ) ) {
      if( !New->ConvertToTool()->CanAddToResource( m_Data, true ) ) {
        delete New;
      } else {
        if( m_Data->InsertNewTool( New->ConvertToTool() ) ) {
          m_Data->SelectItem( New, true );
        }
      }
    } else {
      if( m_Data->InsertNew( New, Reference->ConvertToParent(), -1 ) ) {
        m_Data->SelectItem( New, true );
      }
    }
    break;
  }
  default: {
    delete New;
  }
  }
  m_Data->EndChange();
}

void wxsItemEditor::InitializeImages() {
  if( m_ImagesLoaded ) {
    return;
  }
  wxString basePath = ConfigManager::GetDataFolder() + _T( "/images/wxsmith/" );
  m_InsPointImg.LoadFile( basePath + _T( "insertpoint.png" ) );
  m_InsIntoImg.LoadFile( basePath + _T( "insertinto.png" ) );
  m_InsAfterImg.LoadFile( basePath + _T( "insertafter.png" ) );
  m_InsBeforeImg.LoadFile( basePath + _T( "insertbefore.png" ) );
  m_DelImg.LoadFile( basePath + _T( "deletewidget.png" ) );
  m_PreviewImg.LoadFile( basePath + _T( "showpreview.png" ) );
  m_QuickPropsImgOpen.LoadFile( basePath + _T( "quickpropsopen.png" ) );
  m_QuickPropsImgClose.LoadFile( basePath + _T( "quickpropsclose.png" ) );
  m_SelectedImg.LoadFile( basePath + _T( "selected.png" ) );
  m_ImagesLoaded = true;
}

void wxsItemEditor::OnButton( wxCommandEvent& event ) {
  wxWindow* Btn = ( wxWindow* )event.GetEventObject();
  if( Btn ) {
    InsertRequest( Btn->GetName() );
  }
}

void wxsItemEditor::SetInsertionTypeMask( int Mask ) {
  m_InsTypeMask = Mask;
  SetInsertionType( m_InsType );
}

void wxsItemEditor::SetInsertionType( int Type ) {
  Type &= m_InsTypeMask;
  if( !Type ) {
    Type = m_InsTypeMask;
  }
  if( Type & itPoint ) {
    m_InsType = itPoint;
  } else if( Type & itInto ) {
    m_InsType = itInto;
  } else if( Type & itAfter ) {
    m_InsType = itAfter;
  } else if( Type & itBefore ) {
    m_InsType = itBefore;
  } else {
    m_InsType = 0;
  }
  RebuildInsTypeIcons();
}

void wxsItemEditor::RebuildInsTypeIcons() {
  BuildInsTypeIcon( m_InsPointBtn, m_InsPointImg, itPoint );
  BuildInsTypeIcon( m_InsIntoBtn, m_InsIntoImg, itInto );
  BuildInsTypeIcon( m_InsBeforeBtn, m_InsBeforeImg, itBefore );
  BuildInsTypeIcon( m_InsAfterBtn, m_InsAfterImg, itAfter );
}

void wxsItemEditor::BuildInsTypeIcon( wxBitmapButton* Btn, const wxImage& Original, int ButtonType ) {
  bool Selected = ( m_InsType & ButtonType ) != 0;
  bool Enabled = ( m_InsTypeMask & ButtonType ) != 0;
  if( !Enabled || !Selected ) {
    Btn->SetBitmapLabel( Original );
  } else {
    wxBitmap Copy = Original;
    wxMemoryDC DC;
    DC.SelectObject( Copy );
    DC.DrawBitmap( m_SelectedImg, 0, 0 );
    Btn->SetBitmapLabel( Copy );
  }
  Btn->Enable( Enabled );
  Btn->Refresh();
}

void wxsItemEditor::RebuildQuickPropsIcon() {
  m_QuickPanelBtn->SetBitmapLabel( m_QuickPropsOpen ? m_QuickPropsImgClose : m_QuickPropsImgOpen );
}

void wxsItemEditor::RebuildIcons() {
  RebuildInsTypeIcons();
  RebuildQuickPropsIcon();
  m_DelBtn->SetBitmapLabel( m_DelImg );
  m_PreviewBtn->SetBitmapLabel( m_PreviewImg );
  BuildPalette( m_WidgetsSet );
  Layout();
}

namespace {
  int PrioritySort( const wxsItemInfo** it1, const wxsItemInfo** it2 ) {
    return ( *it1 )->Priority - ( *it2 )->Priority;
  }


  WX_DEFINE_ARRAY( const wxsItemInfo*, ItemsT );

  int CategorySort( ItemsT* it1, ItemsT* it2 ) {
    if( it1->Item( 0 )->Category.IsSameAs( _T( "Standard" ) ) ) {
      return -1;
    }
    if( it2->Item( 0 )->Category.IsSameAs( _T( "Standard" ) ) ) {
      return 1;
    }
    return wxStrcmp( it1->Item( 0 )->Category, it2->Item( 0 )->Category );
  }

  WX_DECLARE_STRING_HASH_MAP( ItemsT, MapT );
  WX_DEFINE_SORTED_ARRAY( ItemsT*, ArrayOfItemsT );
}

void wxsItemEditor::BuildPalette( wxNotebook* Palette ) {  // 控件分类
  Palette->DeleteAllPages();
  bool AllowNonXRCItems = ( m_Data->GetPropertiesFilter() & flSource );
  MapT Map;
  ArrayOfItemsT aoi( CategorySort );
  for( const wxsItemInfo* Info = wxsItemFactory::GetFirstInfo(); Info; Info = wxsItemFactory::GetNextInfo() ) {
    if( !Info->Category.empty() ) {
      Map[Info->Category].Add( Info );
    }
  }
  for( MapT::iterator i = Map.begin(); i != Map.end(); ++i ) {
    aoi.Add( &( i->second ) );
  }
  for( size_t i = 0; i < aoi.Count(); ++i ) {
    ItemsT* Items = aoi.Item( i );
    Items->Sort( PrioritySort );
    wxScrolledWindow* CurrentPanel = new wxScrolledWindow( Palette, -1, wxDefaultPosition, wxDefaultSize, 0 );
    CurrentPanel->SetScrollRate( 1, 0 );
    Palette->AddPage( CurrentPanel, Items->Item( 0 )->Category );
    wxSizer* RowSizer = new wxBoxSizer( wxHORIZONTAL );
    for( size_t j = Items->Count(); j-- > 0; ) {
      const wxsItemInfo* Info = Items->Item( j );
      const wxBitmap& Icon = Info->Icon ;
      if( AllowNonXRCItems || Info->AllowInXRC ) {
        wxWindow* Btn;
        if( Icon.Ok() ) {
          Btn = new wxBitmapButton( CurrentPanel, -1, Icon, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, Info->ClassName );
          RowSizer->Add( Btn, 0, wxALIGN_CENTER );
        } else {
          Btn = new wxButton( CurrentPanel, -1, Info->ClassName, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, Info->ClassName );
          RowSizer->Add( Btn, 0, wxGROW );
        }
        Btn->SetToolTip( Info->name );
      }
    }
    CurrentPanel->SetSizer( RowSizer );
    RowSizer->SetVirtualSizeHints( CurrentPanel );
  }
}

void wxsItemEditor::OnInsPoint( M_Code_unused wxCommandEvent& event ) {
  SetInsertionType( itPoint );
}

void wxsItemEditor::OnInsInto( M_Code_unused wxCommandEvent& event ) {
  SetInsertionType( itInto );
}

void wxsItemEditor::OnInsAfter( M_Code_unused wxCommandEvent& event ) {
  SetInsertionType( itAfter );
}

void wxsItemEditor::OnInsBefore( M_Code_unused wxCommandEvent& event ) {
  SetInsertionType( itBefore );
}

void wxsItemEditor::OnDelete( M_Code_unused wxCommandEvent& event ) {
  if( !m_Data ) {
    return;
  }
  m_Data->BeginChange();
  m_Data->DeleteSelected();
  m_Data->EndChange();
}

void wxsItemEditor::OnPreview( M_Code_unused wxCommandEvent& event ) {
  if( !m_Data ) {
    return;
  }
  m_Content->BlockFetch( true );
  if( m_Data->IsPreview() ) {
    m_Data->HidePreview();
  } else {
    m_Data->ShowPreview();
  }
  m_Content->BlockFetch( false );
}

void wxsItemEditor::OnQuickProps( M_Code_unused wxCommandEvent& event ) {
  m_QuickPropsOpen = !m_QuickPropsOpen;
  RebuildQuickPropsIcon();
  ToggleQuickPropsPanel( m_QuickPropsOpen );
}

void wxsItemEditor::ToggleQuickPropsPanel( bool Open ) {
  m_HorizSizer->Show( m_QPArea, Open, true );
  Layout();
}

void wxsItemEditor::RebuildQuickProps( wxsItem* Selection ) {
  if( !m_Content ) {
    return;
  }
  Freeze();
  int QPx, QPy;
  m_QPArea->GetViewStart( &QPx, &QPy );
  m_QPArea->SetSizer( 0 );
  m_QPArea->DestroyChildren();
  m_QPSizer = new wxBoxSizer( wxVERTICAL );
  m_QPArea->SetSizer( m_QPSizer );
  if( Selection ) {
    wxWindow* QPPanel = Selection->BuildQuickPropertiesPanel( m_QPArea );
    if( QPPanel ) {
      m_QPSizer->Add( QPPanel, 0, wxEXPAND );
    }
  }
  m_QPSizer->Layout();
  m_QPSizer->Fit( m_QPArea );
  Layout();
  m_QPArea->Scroll( QPx, QPy );
  Thaw();
}

wxsItem* wxsItemEditor::GetReferenceItem( int& InsertionType ) {
  wxsItem* Reference = m_Data->GetLastSelection();
  if( !Reference ) {
    InsertionType = itInto;
    Reference = m_Data->GetRootItem();
    wxsParent* AsParent = Reference->ConvertToParent();
    if( AsParent && AsParent->GetChildCount() == 1 && AsParent->GetChild( 0 )->GetType() == wxsTSizer ) {
      Reference = AsParent->GetChild( 0 );
    }
  }
  return Reference;
}

void wxsItemEditor::OnKeyDown( wxKeyEvent& event ) {
  switch( event.GetKeyCode() ) {
  case WXK_DELETE:
    if( !m_Data ) {
      break;
    }
    m_Data->BeginChange();
    m_Data->DeleteSelected();
    m_Data->EndChange();
    break;
  default:
    break;
  }
}

void wxsItemEditor::StartInsertPointSequence( const wxsItemInfo* Info ) {
  if( m_Content ) {
    m_Content->InsertByPointing( Info );
  }
}

void wxsItemEditor::ShowPopup( wxsItem* Item, wxMenu* Popup ) {
  m_PopupCaller = Item;
  PopupMenu( Popup );
}

void wxsItemEditor::OnPopup( wxCommandEvent& event ) {
  if( m_PopupCaller ) {
    if( !m_PopupCaller->PopupMenu( event.GetId() ) ) {
      event.Skip();
    }
  }
}

wxImage wxsItemEditor::m_InsPointImg;
wxImage wxsItemEditor::m_InsIntoImg;
wxImage wxsItemEditor::m_InsBeforeImg;
wxImage wxsItemEditor::m_InsAfterImg;
wxImage wxsItemEditor::m_DelImg;
wxImage wxsItemEditor::m_PreviewImg;
wxImage wxsItemEditor::m_QuickPropsImgOpen;
wxImage wxsItemEditor::m_QuickPropsImgClose;
wxImage wxsItemEditor::m_SelectedImg;
wxsItemEditor::WindowSet wxsItemEditor::m_AllEditors;
bool wxsItemEditor::m_ImagesLoaded = false;

BEGIN_EVENT_TABLE( wxsItemEditor, wxsEditor )
  EVT_BUTTON( wxsInsPointId, wxsItemEditor::OnInsPoint )
  EVT_BUTTON( wxsInsIntoId, wxsItemEditor::OnInsInto )
  EVT_BUTTON( wxsInsBeforeId, wxsItemEditor::OnInsBefore )
  EVT_BUTTON( wxsInsAfterId, wxsItemEditor::OnInsAfter )
  EVT_BUTTON( wxsDelId, wxsItemEditor::OnDelete )
  EVT_BUTTON( wxsPreviewId, wxsItemEditor::OnPreview )
  EVT_BUTTON( wxsQuickPropsId, wxsItemEditor::OnQuickProps )
  EVT_BUTTON( -1, wxsItemEditor::OnButton )
  EVT_KEY_DOWN( wxsItemEditor::OnKeyDown )
  EVT_MENU( wxID_ANY, wxsItemEditor::OnPopup )
END_EVENT_TABLE()
